<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>使用SlimerJS将网页输出为PDF | 在路上</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="本文主要介绍本人在项目实践中通过SlimerJS将网页输出为PDF文档的过程，生成的PDF文档中的文本是矢量的，可以选择复制。虽然网上也有一些类似的分享，但是并没有将整个过程中的可能遇到的坑以及在Web开发中的一些技术细节讲述的比较清楚。 软件清单： xvfb gtk3 cups firefox slimerjs  本文使用的操作系统版本为CentOS 7.2。 安装xvfb关于xvfb的介绍可以">
<meta name="keywords" content="SlimerJS">
<meta property="og:type" content="article">
<meta property="og:title" content="使用SlimerJS将网页输出为PDF">
<meta property="og:url" content="http://yoursite.com/2016/06/29/slimerjs/index.html">
<meta property="og:site_name" content="在路上">
<meta property="og:description" content="本文主要介绍本人在项目实践中通过SlimerJS将网页输出为PDF文档的过程，生成的PDF文档中的文本是矢量的，可以选择复制。虽然网上也有一些类似的分享，但是并没有将整个过程中的可能遇到的坑以及在Web开发中的一些技术细节讲述的比较清楚。 软件清单： xvfb gtk3 cups firefox slimerjs  本文使用的操作系统版本为CentOS 7.2。 安装xvfb关于xvfb的介绍可以">
<meta property="og:locale" content="zh-CN">
<meta property="og:updated_time" content="2018-03-26T11:35:06.699Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="使用SlimerJS将网页输出为PDF">
<meta name="twitter:description" content="本文主要介绍本人在项目实践中通过SlimerJS将网页输出为PDF文档的过程，生成的PDF文档中的文本是矢量的，可以选择复制。虽然网上也有一些类似的分享，但是并没有将整个过程中的可能遇到的坑以及在Web开发中的一些技术细节讲述的比较清楚。 软件清单： xvfb gtk3 cups firefox slimerjs  本文使用的操作系统版本为CentOS 7.2。 安装xvfb关于xvfb的介绍可以">
  
    <link rel="alternate" href="/atom.xml" title="在路上" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link rel="stylesheet" href="/css/style.css">
</head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">在路上</a>
      </h1>
      
        <h2 id="subtitle-wrap">
          <a href="/" id="subtitle">一位崇尚价值投资的 Web 开发者</a>
        </h2>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="搜索"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://yoursite.com"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main"><article id="post-slimerjs" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2016/06/29/slimerjs/" class="article-date">
  <time datetime="2016-06-28T16:00:00.000Z" itemprop="datePublished">2016-06-29</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      使用SlimerJS将网页输出为PDF
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>本文主要介绍本人在项目实践中通过<code>SlimerJS</code>将网页输出为PDF文档的过程，生成的PDF文档中的文本是矢量的，可以选择复制。<br>虽然网上也有一些类似的分享，但是并没有将整个过程中的可能遇到的坑以及在Web开发中的一些技术细节讲述的比较清楚。</p>
<h2 id="软件清单："><a href="#软件清单：" class="headerlink" title="软件清单："></a>软件清单：</h2><ul>
<li>xvfb</li>
<li>gtk3</li>
<li>cups</li>
<li>firefox</li>
<li>slimerjs</li>
</ul>
<p>本文使用的操作系统版本为CentOS 7.2。</p>
<h2 id="安装xvfb"><a href="#安装xvfb" class="headerlink" title="安装xvfb"></a>安装xvfb</h2><p>关于xvfb的介绍可以查看<a href="https://en.wikipedia.org/wiki/Xvfb" target="_blank" rel="noopener">wiki</a>，简单点说它就是用于处理程序中与图形化相关的功能，但是它不会在屏幕上展示任何图形输出。<br>安装以后可以使用<strong>xvfb-run</strong>命令来运行<strong>headless slimerjs.</strong></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install xorg-x11-server-Xvfb</span><br></pre></td></tr></table></figure>
<h2 id="安装Firefox"><a href="#安装Firefox" class="headerlink" title="安装Firefox"></a>安装Firefox</h2><p>SlimerJS依赖于Firefox，目前支持的版本号介于38~ 46，其它版本官方无法保证测试结果。<br>所以不推荐安装大于46或者小于38的版本。</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">wget https://ftp.mozilla.org/pub/firefox/releases/46.0.1/linux-x86_64-EME-free/zh-CN/firefox-46.0.1.tar.bz2</span><br><span class="line">tar xjvf firefox-46.0.1.tar.bz2</span><br></pre></td></tr></table></figure>
<p>注意这里我们下载Firefox的版本号为64的<a href="https://wiki.mozilla.org/Media/EME" target="_blank" rel="noopener">EME</a>版本，普通版本在渲染复杂网页时可能会出现莫名的引擎级别错误。</p>
<h2 id="安装GTK3"><a href="#安装GTK3" class="headerlink" title="安装GTK3"></a>安装GTK3</h2><p>由于Firefox 46<a href="https://www.mozilla.org/en-US/firefox/46.0/system-requirements/" target="_blank" rel="noopener">依赖</a>于GTK3，所以这里我们需要安装GTK3。<br>另外如果你的操作系统版本为CentOS 6.x，那么我推荐你<a href="http://itvision.altervista.org/compiling-and-installing-gtk3-in-centos6.html" target="_blank" rel="noopener">放弃安装GTK3</a>，而是直接升级系统。</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install gtk3-devel</span><br></pre></td></tr></table></figure>
<h2 id="安装CUPS"><a href="#安装CUPS" class="headerlink" title="安装CUPS"></a>安装CUPS</h2><p><a href="https://www.cups.org/" target="_blank" rel="noopener">CUPS</a>是由苹果开发的通用Unix打印系统，如果没有安装CUPS，SlimerJS将网页渲染为PDF的时候将会<a href="https://docs.slimerjs.org/current/faq.html#on-linux-pdf-rendering-hangs-slimerjs" target="_blank" rel="noopener">挂起</a>。</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install cups</span><br></pre></td></tr></table></figure>
<h2 id="安装SlimerJS"><a href="#安装SlimerJS" class="headerlink" title="安装SlimerJS"></a>安装SlimerJS</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">wget http://download.slimerjs.org/releases/0.10.0/slimerjs-0.10.0.zip</span><br><span class="line">unzip slimerjs-0.10.0.zip</span><br></pre></td></tr></table></figure>
<h2 id="设置环境变量"><a href="#设置环境变量" class="headerlink" title="设置环境变量"></a>设置环境变量</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">// 这里设置为firefox文件夹下的的firefox可执行文件的路径</span><br><span class="line">export SLIMERJSLAUNCHER=PATH_TO_FIREFOX</span><br></pre></td></tr></table></figure>
<h2 id="开始执行"><a href="#开始执行" class="headerlink" title="开始执行"></a>开始执行</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd PATH_TO_SLIMERJS</span><br><span class="line">xvfb-run ./slimerjs SCRIPT_PATH HTTP_PAGE_URL OUTPUT_FILENAME</span><br></pre></td></tr></table></figure>
<p>另外如果执行没有正常运行，可以加上—debug参数</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">xvfb-run ./slimerjs --debug test.js http://www.qq.com/ test.pdf</span><br></pre></td></tr></table></figure>
<h2 id="参考代码"><a href="#参考代码" class="headerlink" title="参考代码"></a>参考代码</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> page = <span class="built_in">require</span>(<span class="string">'webpage'</span>).create()</span><br><span class="line"><span class="keyword">var</span> system = <span class="built_in">require</span>(<span class="string">'system'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (system.args.length !== <span class="number">3</span>) &#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'Arguments error: xvfb-run ./slimerjs SCRIPT_PATH HTTP_PAGE_URL OUTPUT_FILENAME'</span>)</span><br><span class="line">  slimer.exit()</span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">  <span class="keyword">var</span> url = system.args[<span class="number">1</span>]</span><br><span class="line">  <span class="keyword">var</span> renderPath = system.args[<span class="number">2</span>]</span><br><span class="line"></span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'Page url is '</span> + url)</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'Output path is '</span> + renderPath)</span><br><span class="line"></span><br><span class="line">  page.paperSize = &#123;</span><br><span class="line">    <span class="comment">// magic number in my project</span></span><br><span class="line">    width: <span class="string">'1500px'</span>,</span><br><span class="line">    height: <span class="string">'1038px'</span>,</span><br><span class="line">    shrinkToFit: <span class="literal">true</span>,</span><br><span class="line">    printBGColors: <span class="literal">true</span>,</span><br><span class="line">    printBGImages: <span class="literal">true</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  page.onLoadFinished = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'Finish loading page'</span>)</span><br><span class="line">    <span class="comment">// 有些时候分页不理想，需要删除一些节点</span></span><br><span class="line">    page.evaluate(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="keyword">var</span> nodes = <span class="built_in">document</span>.querySelectorAll(<span class="string">'.bottom-line'</span>)</span><br><span class="line">      <span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>; i&lt; nodes.length; i += <span class="number">1</span>) &#123;</span><br><span class="line">        nodes[i].parentNode.removeChild(nodes[i])</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'Start rendering'</span>)</span><br><span class="line">    page.render(renderPath)</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'Finish rendering'</span>)</span><br><span class="line">    slimer.exit()</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'Opening page now ...'</span>)</span><br><span class="line">  page.open(url)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="字体"><a href="#字体" class="headerlink" title="字体"></a>字体</h2><p>由于服务部署在Linux服务器上，网页渲染使用的字体与Windows和macOS区别还是很大的，比如Windows的微软雅黑在Linux是无法使用的。<br>另外在安装字体上也有两种选择，第一是直接安装在服务器上，第二是作为Web Fonts从网页中引入。</p>
<h2 id="Flex布局"><a href="#Flex布局" class="headerlink" title="Flex布局"></a>Flex布局</h2><p>早先我们尝试使用PhantomJS来完成此工作，虽然网上有说2.x支持Flex布局，但是我们的实践结果是不支持。SlimerJS在Flex布局上支持的很好，无需任何额外工作。</p>
<h2 id="Canvas绘制"><a href="#Canvas绘制" class="headerlink" title="Canvas绘制"></a>Canvas绘制</h2><p>我们的网页使用了ECharts来进行图表绘制，ECharts底层使用了canvas来绘制图表。<br>PhantomJS输出的PDF在这方面支持很差，Stacked Column中莫名的出现很多空白间隙。SlimerJS的表现要好得多，不过有些淡虚线比实际要粗一些，色彩也深一些。</p>
<h2 id="文档分页"><a href="#文档分页" class="headerlink" title="文档分页"></a>文档分页</h2><p>如果希望输出的PDF能够支持分页输出（方便分页打印），需要设置paperSize的Height来确定每页pdf的高度。<br>不过这里也是有坑的，每页PDF高度会有几个像素的差距，导致会多出一个空白页。</p>
<h2 id="CSS适配"><a href="#CSS适配" class="headerlink" title="CSS适配"></a>CSS适配</h2><p>渲染PDF的时候，浏览器进入打印模式，如果你没有专门适配样式，输出效果会很差。很多元素的背景颜色/文本颜色/背景图片不会展示出来。<br>对于PhantomJS，网上有讨论说需要加上如下样式（我本人并未实践过此方案）：</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">@<span class="keyword">media</span> print &#123;</span><br><span class="line">  <span class="selector-tag">body</span> &#123;</span><br><span class="line">     <span class="comment">/*https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-print-color-adjust*/</span></span><br><span class="line">     <span class="attribute">-webkit-print-color-adjust</span>: exact;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>对于SlimerJS，虽然paperSize存在相关设置（printBGColors/printBGImages），但是文本颜色似乎无法设置。所以我推荐在编写CSS的时候注意如下细节：</p>
<ul>
<li>将所有背景图片转换为Base64字符串直接在css中引入（幸好有webpack）</li>
<li>所有设置元素文本颜色和背景颜色的样式需要兼容打印模式</li>
<li>文本颜色相关的设置不支持inherited，这点尤其注意</li>
</ul>
<p>样例代码如下：</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.someClassName</span> &#123;</span><br><span class="line">  <span class="attribute">background-color</span>:red;</span><br><span class="line">  <span class="attribute">color</span>: <span class="number">#FFF</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">@<span class="keyword">media</span> print &#123;</span><br><span class="line">  <span class="selector-class">.someClassName</span> &#123;</span><br><span class="line">    <span class="attribute">background-color</span>:red <span class="meta">!important</span>;</span><br><span class="line">    <span class="attribute">color</span>: <span class="number">#FFF</span> <span class="meta">!important</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="最后的忠告"><a href="#最后的忠告" class="headerlink" title="最后的忠告"></a>最后的忠告</h2><p><em>不要寄希望于输出的PDF与网页中展示效果100%一致，几乎不可能（尤其是网页内容相对比较复杂的时候），最终效果或多或少都会有些瑕疵。</em></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2016/06/29/slimerjs/" data-id="cjf865ufu00178wp14htbrhqg" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/SlimerJS/">SlimerJS</a></li></ul>

    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2016/07/17/parser/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          JavaScript Parser资源总结
        
      </div>
    </a>
  
  
    <a href="/2016/06/26/code-management/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">代码管理</div>
    </a>
  
</nav>

  
</article>

</section>
        
          <aside id="sidebar">
  
    

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">标签</h3>
    <div class="widget">
      <ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/tags/JavaScript/">JavaScript</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/JavaScript-解析器/">JavaScript,解析器</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/React/">React</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Redux/">Redux</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/SlimerJS/">SlimerJS</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/代码管理/">代码管理</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/持续集成/">持续集成</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">标签云</h3>
    <div class="widget tagcloud">
      <a href="/tags/JavaScript/" style="font-size: 20px;">JavaScript</a> <a href="/tags/JavaScript-解析器/" style="font-size: 10px;">JavaScript,解析器</a> <a href="/tags/React/" style="font-size: 16.67px;">React</a> <a href="/tags/Redux/" style="font-size: 10px;">Redux</a> <a href="/tags/SlimerJS/" style="font-size: 10px;">SlimerJS</a> <a href="/tags/代码管理/" style="font-size: 10px;">代码管理</a> <a href="/tags/持续集成/" style="font-size: 13.33px;">持续集成</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">归档</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/09/">九月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/07/">七月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/06/">六月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/03/">三月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/02/">二月 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/12/">十二月 2015</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/06/">六月 2015</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/05/">五月 2015</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/04/">四月 2015</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2014/07/">七月 2014</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2014/06/">六月 2014</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2012/11/">十一月 2012</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2012/10/">十月 2012</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2012/07/">七月 2012</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2012/03/">三月 2012</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2012/02/">二月 2012</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2011/10/">十月 2011</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2010/01/">一月 2010</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/1970/01/">一月 1970</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2016/09/09/space/">空格</a>
          </li>
        
          <li>
            <a href="/2016/07/17/parser/">JavaScript Parser资源总结</a>
          </li>
        
          <li>
            <a href="/2016/06/29/slimerjs/">使用SlimerJS将网页输出为PDF</a>
          </li>
        
          <li>
            <a href="/2016/06/26/code-management/">代码管理</a>
          </li>
        
          <li>
            <a href="/2016/06/18/violet/">violet - 值得一试的写作同步小助手</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2018 Simon Xu<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/script.js"></script>



  </div>
</body>
</html>